[POWERPC][XEN] Clear SLB entries on boot and other cleanups
authorJimi Xenidis <jimix@watson.ibm.com>
Thu, 7 Sep 2006 06:21:17 +0000 (02:21 -0400)
committerJimi Xenidis <jimix@watson.ibm.com>
Thu, 7 Sep 2006 06:21:17 +0000 (02:21 -0400)
This patch clears and SLB entries that might have been left behind by
Firmware and also cleans up the Save and Restore of the segments.

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
xen/arch/powerpc/powerpc64/domain.c
xen/arch/powerpc/powerpc64/ppc970.c
xen/include/asm-powerpc/domain.h
xen/include/asm-powerpc/processor.h

index a6473348c3bb09c64e135ddd71ae5d72fbca5eb1..2714a7917ba1a7d75f55274db24ec1b97f4451da 100644 (file)
@@ -63,24 +63,31 @@ void load_sprs(struct vcpu *v)
 
 /* XXX evaluate all isyncs in segment code */
 
-static void flush_slb(struct vcpu *v)
+void flush_segments(void)
 {
-    struct slb_entry *slb0 = &v->arch.slb_entries[0];
+    struct slb_entry slb0;
+    ulong zero = 0;
 
-    slbia();
+    __asm__ __volatile__(
+        "slbmfev %0,%2\n"
+        "slbmfee %1,%2\n"
+        :"=&r"(slb0.slb_vsid), "=&r"(slb0.slb_esid)
+        :"r"(zero)
+        :"memory");
 
     /* we manually have to invalidate SLB[0] since slbia doesn't. */
     /* XXX name magic constants! */
-    if (slb0->slb_esid & (1 << (63 - 36))) {
+    if (slb0.slb_esid & SLB_ESID_VALID) {
         ulong rb;
         ulong class;
 
-        class = (slb0->slb_vsid >> (63 - 56)) & 1ULL;
-        rb = slb0->slb_esid & (~0ULL << (63 - 35));
-        rb |= class << (63 - 36);
+        class = !!(slb0.slb_vsid & SLB_ESID_CLASS);
+        rb = slb0.slb_esid & SLB_ESID_MASK;
+        rb |= class << SLBIE_CLASS_LOG;
 
         slbie(rb);
     }
+    slbia();
 }
 
 void save_segments(struct vcpu *v)
@@ -111,7 +118,7 @@ void save_segments(struct vcpu *v)
 #endif
     }
 
-    flush_slb(v);
+    flush_segments();
 }
 
 void load_segments(struct vcpu *v)
@@ -126,7 +133,8 @@ void load_segments(struct vcpu *v)
 
         /* FIXME: should we bother to restore invalid entries */
         /* stuff in the index here */
-        esid |= i & ((0x1UL << (63 - 52 + 1)) - 1);
+        esid &= ~SLBMTE_ENTRY_MASK;
+        esid |= i;
 
         __asm__ __volatile__(
                 "isync\n"
@@ -144,3 +152,27 @@ void load_segments(struct vcpu *v)
 #endif
     }
 }
+
+void dump_segments(int valid)
+{
+    int i;
+
+    printk("Dump %s SLB entries:\n", valid ? "VALID" : "ALL");
+
+    /* save all extra SLBs */
+    for (i = 0; i < NUM_SLB_ENTRIES; i++) {
+        ulong vsid;
+        ulong esid;
+
+        __asm__ __volatile__(
+                "slbmfev %0,%2\n"
+                "slbmfee %1,%2\n"
+                :"=&r"(vsid), "=&r"(esid)
+                :"r"(i)
+                :"memory");
+
+        if (valid && !(esid & SLB_ESID_VALID))
+            continue;
+        printf("S%02d: 0x%016lx 0x%016lx\n", i, vsid, esid);
+    }
+}
index 21ac2251016d84b29615564eac2a2f2204175474..7b0f2c7a9f4a782e48d3490c29fd6db80a2a96de 100644 (file)
@@ -202,8 +202,10 @@ void cpu_initialize(int cpuid)
 
     mthior(cpu0_hior);
 
-    /* for good luck */
-    __asm__ __volatile__("isync; slbia; isync" : : : "memory");
+#ifdef DEBUG
+    dump_segments(1);
+#endif
+    flush_segments();
 }
 
 void cpu_init_vcpu(struct vcpu *v)
index 6f21f6d5fe50785ed898558d61f7608bbb069474..304cb6c9508ff2934923d6e4db9cc236c31ec80b 100644 (file)
@@ -52,6 +52,11 @@ struct slb_entry {
     ulong slb_vsid;
     ulong slb_esid;
 };
+#define SLB_ESID_VALID (1ULL << (63 - 36))
+#define SLB_ESID_CLASS (1ULL << (63 - 56))
+#define SLB_ESID_MASK  (~0ULL << (63 - 35))
+#define SLBIE_CLASS_LOG (63-36)
+#define SLBMTE_ENTRY_MASK ((0x1UL << (63 - 52 + 1)) - 1)
 
 struct xencomm;
 
index 4772d7ffe27ce3dbe3aa20795c8f85a0834bb6cc..6b949701b16bfd8b733012efb860357d7254f576 100644 (file)
@@ -50,6 +50,8 @@ extern void cpu_init_vcpu(struct vcpu *);
 extern int cpu_io_mfn(ulong mfn);
 extern void save_cpu_sprs(struct vcpu *);
 extern void load_cpu_sprs(struct vcpu *);
+extern void flush_segments(void);
+extern void dump_segments(int valid);
 
 /* XXX this could also land us in GDB */
 #define dump_execution_state() BUG()